package com.xinyue.game.logic.frame;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import com.xinyue.game.logic.frame.handler.GameMessageHandler;
import com.xinyue.game.logic.frame.handler.GameRequestMapping;
import com.xinyue.game.logic.frame.handler.HandlerMethod;
import com.xinyue.network.message.stream.GameMessageMetadata;
import com.xinyue.network.message.stream.IGameMessage;

public class GameRequestHandlerContext {

	private ApplicationContext context;
	private Map<Integer, Class<? extends IGameMessage>> gameMessageClassMap = new HashMap<>();
	private Map<Integer, HandlerMethod> handlerMethodMap = new HashMap<>();
	private static Logger logger = LoggerFactory.getLogger(GameRequestHandlerContext.class);
	
	public GameRequestHandlerContext(ApplicationContext context) {
		this.context = context;
	}
	
	@PostConstruct
	public void init() {
		Map<String, Object> beans = context.getBeansWithAnnotation(GameMessageHandler.class);
		if(beans != null && beans.size() > 0) {
			beans.values().forEach(obj->{
				Method[] methods = obj.getClass().getMethods();
				if(methods != null) {
					for(Method method : methods) {
						GameRequestMapping gameRequestMapping = method.getAnnotation(GameRequestMapping.class);
						if(gameRequestMapping != null) {
							
							Class<? extends IGameMessage> clazz = gameRequestMapping.value();
							GameMessageMetadata gameMetadata = clazz.getAnnotation(GameMessageMetadata.class);
							int id = gameMetadata.messageId();
							gameMessageClassMap.put(id, clazz);
							HandlerMethod handlerMethod = new HandlerMethod(obj, method);
							handlerMethodMap.put(id, handlerMethod);
						}
					}
				}
			});
		}
	}
	
	public IGameMessage getRequestMessage(int messageId) {
		
		Class<? extends IGameMessage> value = this.gameMessageClassMap.get(messageId);
		if(value != null) {
			try {
				return value.newInstance();
			} catch (InstantiationException | IllegalAccessException e) {
				logger.error("获取请求消息 实例失败",e);
				return null;
			}
		}
		return null;
	}
	
	public  HandlerMethod getHandlerMethod(int messageId) {
		return this.handlerMethodMap.get(messageId);
	}
}
